package com.gzy.gameserver;

import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.awt.geom.Point2D;
import java.awt.geom.Point2D.Float;
import java.io.Serializable;
import com.sun.sgs.app.AppContext;
import com.sun.sgs.app.DataManager;
import com.sun.sgs.app.ManagedObject;
import com.sun.sgs.app.ManagedReference;

/**
 * 
 * @author gzy : WorldObject that has a name and desciption
 *
 */
public class WorldObject
implements Serializable, ManagedObject
{
	/**The version of the serialized form of this class */
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger(WorldObject.class.getName());
	
	protected String 		m_name;
	protected Point2D.Float m_location = new Point2D.Float(0, 0);
	protected Dir2D			m_dir = new Dir2D(Dir2D.front_dir);
	protected boolean		m_canBeBlock = false;
	protected boolean		m_bRemoveFromWorld = false;

	private ManagedReference<World> m_currentWorldRef;
	
	private String m_description;
	
	protected UUID m_uuid;
	
	public WorldObject(String name, String desc)
	{
		this.m_name = name;
		this.m_description = desc;
		this.m_uuid = UUID.randomUUID();
	}

	public UUID getID()
	{
		return m_uuid;
	}

	protected void cleanupTarget()
	{
		
	}
	
	public void leave()
	{
		setWorld(null);
	}
	
	public void setDir(Point2D.Float dir)
	{
		this.m_dir.setDir(dir);
	}
	public Dir2D getDir()
	{
		return this.m_dir;
	}
	
	public void setCanBeBlock(boolean canBeBlock)
	{
		this.m_canBeBlock = canBeBlock;
	}
	
	public boolean getCanBeBlock()
	{
		return this.m_canBeBlock;
	}
	
	protected World getWorld()
	{
		if (this.m_currentWorldRef == null)
			return null;
		
		return this.m_currentWorldRef.get();
	}
	
	protected void setWorld(World world)
	{
		if (world == null)
		{
			this.m_currentWorldRef = null;
			return;
		}

		DataManager dataMgr = AppContext.getDataManager();
		dataMgr.markForUpdate(this);
		
		this.m_currentWorldRef = dataMgr.createReference(world);
	}

	public void setName(String name)
	{
		AppContext.getDataManager().markForUpdate(this);
		this.m_name = name;
	}
	
	public String getName()
	{
		return this.m_name;
	}
	public byte[] getNameUtf8()
	{
		try{
			return this.m_name.getBytes("UTF-8");
		}catch(Exception e){
			logger.log(Level.INFO, "{0}", e);
			return this.m_name.getBytes();
		}
	}

	public String toString()
	{
		return this.m_name + ":uuid=" + this.m_uuid.toString();
	}
	
	public Point2D.Float getLocation()
	{
		return m_location;
	}
	

	public void setLocation(Point2D.Float location)
	{
		this.setLocation(location.x, location.y);
	}
	
	public void blockTrigger(byte flag){ }
	public void setLocation(float locX, float locY)
	{

		if (this.m_canBeBlock)
		{
			Point2D.Float dir = this.m_dir.getDir2D();
			Point2D.Float checkPos = new Point2D.Float(locX + (dir.x>0?1.f:-1.f), locY + (dir.y>0?1.f:-1.f));
			byte flag = this.m_currentWorldRef.get().getFlag(checkPos);
			blockTrigger(flag);
			switch (flag)
			{
			case World.EMapFlag_Block:
				return;
			}
		}

		this.m_location.x = locX; this.m_location.y = locY;
	}
	
	public void setDescription(String desc)
	{
		AppContext.getDataManager().markForUpdate(this);
		this.m_description = desc;
	}
	
	public String getDescription()
	{
		return this.m_description;
	}
}
